using Circus.CodeEditor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
namespace Circus.CodeEditor.TextSource
{
	public class CodeSnippetRanges : SortList<CodeSnippetRange>, IList<CodeSnippetRange>, ICollection<CodeSnippetRange>, IEnumerable<CodeSnippetRange>, IEnumerable
	{
		private class SnippetComparer : IComparer<CodeSnippetRange>
		{
			public int Compare(CodeSnippetRange x, CodeSnippetRange y)
			{
				Point startPoint = x.StartPoint;
				Point startPoint2 = y.StartPoint;
				int num = startPoint.Y - startPoint2.Y;
				if (num == 0)
				{
					num = startPoint.X - startPoint2.X;
				}
				return num;
			}
		}
		private IComparer<CodeSnippetRange> snippetComparer;
		protected bool IsEditableRangeSelected(CodeSnippetRange range, Rectangle rect)
		{
			return range.IsEditable && range.StartPoint.Equals(rect.Location) && range.EndPoint.Equals(new Point(rect.Right, rect.Bottom));
		}
		public CodeSnippetRanges()
		{
			this.snippetComparer = new CodeSnippetRanges.SnippetComparer();
		}
		public bool NeedClear(int y)
		{
			return base.Count != 0 && (base[0].StartPoint.Y > y || base[base.Count - 1].EndPoint.Y < y);
		}
		public bool NeedClear(Rectangle rect)
		{
			return this.NeedClear(rect.Top) || this.NeedClear(rect.Bottom);
		}
		public virtual bool PositionChanged(int x, int y, int deltaX, int deltaY, bool preserveBounds)
		{
			bool result = false;
			Point point = new Point(x, y);
			int num;
			if (!base.FindLast(new CodeSnippetRange(point, point), out num, this.snippetComparer))
			{
				num--;
			}
			for (int i = Math.Max(num, 0); i < base.Count; i++)
			{
				CodeSnippetRange codeSnippetRange = base[i];
				point = codeSnippetRange.StartPoint;
				Point endPoint = codeSnippetRange.EndPoint;
				if (deltaY == 0 && point.Y > y)
				{
					break;
				}
				if (SortList<CodeSnippetRange>.UpdatePos(x, y, deltaX, deltaY, ref point, !preserveBounds && codeSnippetRange.ID != string.Empty && codeSnippetRange.IsEditable))
				{
					codeSnippetRange.StartPoint = point;
					result = true;
				}
				if (SortList<CodeSnippetRange>.UpdatePos(x, y, deltaX, deltaY, ref endPoint, preserveBounds || codeSnippetRange.ID == string.Empty || !codeSnippetRange.IsEditable))
				{
					codeSnippetRange.EndPoint = endPoint;
					result = true;
				}
			}
			return result;
		}
		public virtual bool BlockDeleting(Rectangle rect)
		{
			bool flag = false;
			Point point = new Point(rect.Right, rect.Bottom);
			int num;
			if (base.FindLast(new CodeSnippetRange(point, point), out num, this.snippetComparer))
			{
				num++;
			}
			for (int i = Math.Min(num, base.Count - 1); i >= 0; i--)
			{
				CodeSnippetRange codeSnippetRange = base[i];
				if (codeSnippetRange.StartPoint.Y < rect.Top)
				{
					break;
				}
				if (!this.IsEditableRangeSelected(codeSnippetRange, rect) && SortList<CodeSnippetRange>.InsideRange(codeSnippetRange.StartPoint, rect) && (SortList<CodeSnippetRange>.InsideRange(codeSnippetRange.EndPoint, rect, true) || codeSnippetRange.EndPoint.Equals(new Point(rect.Right, rect.Bottom))))
				{
					base.RemoveAt(i);
					flag = true;
				}
			}
			if (flag && base.Count == 1)
			{
				CodeSnippetRange codeSnippetRange = base[0];
				if (codeSnippetRange.ID == string.Empty && !codeSnippetRange.IsEditable)
				{
					base.RemoveAt(0);
				}
			}
			return flag;
		}
		public int GetFirstSnippet()
		{
			int result;
			for (int i = 0; i < base.Count; i++)
			{
				CodeSnippetRange codeSnippetRange = base[i];
				if (codeSnippetRange.ID != string.Empty && codeSnippetRange.IsEditable)
				{
					result = i;
					return result;
				}
			}
			result = -1;
			return result;
		}
		public int GetNextSnippet(int index)
		{
			CodeSnippetRange codeSnippetRange = base[index];
			int result;
			for (int i = index + 1; i < base.Count; i++)
			{
				CodeSnippetRange codeSnippetRange2 = base[i];
				if (codeSnippetRange2.ID != string.Empty && codeSnippetRange2.ID != codeSnippetRange.ID && codeSnippetRange2.IsEditable && this.IsFirstSnippet(i))
				{
					result = i;
					return result;
				}
			}
			for (int i = 0; i < index; i++)
			{
				CodeSnippetRange codeSnippetRange2 = base[i];
				if (codeSnippetRange2.ID != string.Empty && codeSnippetRange2.IsEditable && codeSnippetRange2.ID != codeSnippetRange.ID && this.IsFirstSnippet(i))
				{
					result = i;
					return result;
				}
			}
			result = index;
			return result;
		}
		public int GetPrevSnippet(int index)
		{
			CodeSnippetRange codeSnippetRange = base[index];
			int result;
			for (int i = index - 1; i >= 0; i--)
			{
				CodeSnippetRange codeSnippetRange2 = base[i];
				if (codeSnippetRange2.ID != string.Empty && codeSnippetRange2.ID != codeSnippetRange.ID && codeSnippetRange2.IsEditable && this.IsFirstSnippet(i))
				{
					result = i;
					return result;
				}
			}
			for (int i = base.Count - 1; i > index; i--)
			{
				CodeSnippetRange codeSnippetRange2 = base[i];
				if (codeSnippetRange2.ID != string.Empty && codeSnippetRange2.IsEditable && codeSnippetRange2.ID != codeSnippetRange.ID && this.IsFirstSnippet(i))
				{
					result = i;
					return result;
				}
			}
			result = index;
			return result;
		}
		public bool IsFirstSnippet(CodeSnippetRange range)
		{
			int num = base.IndexOf(range);
			return num >= 0 && this.IsFirstSnippet(num);
		}
		public bool IsFirstSnippet(int index)
		{
			CodeSnippetRange codeSnippetRange = base[index];
			bool result;
			for (int i = index - 1; i >= 0; i--)
			{
				string iD = base[i].ID;
				if (iD == codeSnippetRange.ID)
				{
					result = false;
					return result;
				}
			}
			result = true;
			return result;
		}
		public bool FindSnippet(Point position, bool exact, out int index)
		{
			bool flag = base.FindLast(new CodeSnippetRange(position, position), out index, this.snippetComparer);
			bool result;
			if (!exact && !flag)
			{
				index--;
				if (index >= 0 && index < base.Count)
				{
					Range range = base[index];
					if ((range.StartPoint.Y < position.Y || (range.StartPoint.Y == position.Y && range.StartPoint.X <= position.X)) && (range.EndPoint.Y > position.Y || (range.EndPoint.Y == position.Y && range.EndPoint.X >= position.X)))
					{
						result = true;
						return result;
					}
				}
			}
			result = flag;
			return result;
		}
		public new void Sort()
		{
			base.Sort(this.snippetComparer);
		}
	}
}
